<?php

abstract class Duplo {

    static $PARSE_NEXT_PARAM = true;

    /*
     * Executes method %method%Action. Acts in different ways when called with different $method-types.
     *      bool false (default) - executes defaultAction.
     *      bool true - tries to fetch next param from UriDecoder, and calls %nextParam%Action
     *      string %method% - calls %method%Action
     *
     * //Throws Exception.
     * Generates warning.
     */
    public function run($method = false) {
        $methodToCall = 'default';
        if (is_bool($method)) {
            if ($method) {
                $upcomingMethod = UriHelper::getNext();
                if ((string)$upcomingMethod != '') {
                    $methodToCall = $upcomingMethod;
                }
            }
        } elseif (is_string($method)) {
            $methodToCall = $method;
        }
        $methodName = $methodToCall.'Action';
        if (method_exists($this, $methodName)) {
            $this->output = call_user_func(array($this, $methodName));
        } else {
            trigger_error('Class '.__CLASS__.' has no method '.$methodName.'.', E_USER_WARNING);
            $methodName = 'errorAction';
            $this->output = call_user_func(array($this, $methodName));
        }
    }

    protected abstract function defaultAction();
    protected abstract function errorAction();
    protected abstract function getDir();

    /*
     * When creating new duplo-element it's necessary to add requirements of new created element to the current one,
     * such as styles, javascripts... 
     */
    protected function addRequirements ($req) {
        foreach ($req as $ext => $list) {
            $this->requirements[$ext] = array_merge($this->requirements[$ext], $list);
            $this->requirements[$ext] = array_unique($this->requirements[$ext]);
        }
    }
    
    protected function getRequirements () {
        return $this->requirements;
    }

    private function initRequirements () {
        $dirToSeek = $this->getDir();
        foreach ($this->requirements as $ext => $list) {
            $this->requirements[$ext] = FileSystem::getFilesByExtension($dirToSeek, $ext);
        }
        
    }

    public function getOutput () {
        return $this->output;
    }

    public function Duplo () {
        $this->initRequirements();
    }

    private $output;
    private $requirements = array('css' => array(), 'js' => array());

}
